package bbs.service.impl;

import bbs.entity.dto.*;
import bbs.entity.enums.PageSize;
import bbs.entity.enums.SysSettingCodeEnum;
import bbs.entity.po.SysSetting;
import bbs.entity.query.SimplePage;
import bbs.entity.query.SysSettingQuery;
import bbs.entity.vo.PaginationResultVO;
import bbs.exception.BusinessException;
import bbs.mappers.SysSettingMapper;
import bbs.service.SysSettingService;
import bbs.utils.JsonUtils;
import bbs.utils.StringTools;
import bbs.utils.SysCacheUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;


/**
 * 系统设置信息 业务接口实现
 */
@Service("sysSettingService")
public class SysSettingServiceImpl implements SysSettingService {

	private static final Logger logger = LoggerFactory.getLogger(SysSettingServiceImpl.class);

	@Resource
	private SysSettingMapper<SysSetting, SysSettingQuery> sysSettingMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<SysSetting> findListByParam(SysSettingQuery param) {
		return this.sysSettingMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(SysSettingQuery param) {
		return this.sysSettingMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<SysSetting> findListByPage(SysSettingQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<SysSetting> list = this.findListByParam(param);
		PaginationResultVO<SysSetting> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(SysSetting bean) {
		return this.sysSettingMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<SysSetting> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.sysSettingMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<SysSetting> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.sysSettingMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(SysSetting bean, SysSettingQuery param) {
		StringTools.checkParam(param);
		return this.sysSettingMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(SysSettingQuery param) {
		StringTools.checkParam(param);
		return this.sysSettingMapper.deleteByParam(param);
	}


//	@Override
//	public SysSettingDto refresCache() {
//		try {
//			SysSettingDto sysSettingDto = new SysSettingDto();
//			List<SysSetting> list = sysSettingMapper.selectList(new SysSettingQuery());
//			for (SysSetting sysSetting : list) {
//				String jsonContent = sysSetting.getJsonContent();
//				if (StringTools.isEmpty(jsonContent)) {
//					continue;
//				}
//				String code = sysSetting.getCode();
//				SysSettingCodeEnum sysSettingCodeEnum = SysSettingCodeEnum.getByCode(code);
//				PropertyDescriptor pd = new PropertyDescriptor(sysSettingCodeEnum.getPropName(), SysSettingDto.class);
//				Method method = pd.getWriteMethod();
//				Class subClassz = Class.forName(sysSettingCodeEnum.getClassz());
//				method.invoke(sysSettingDto, JsonUtils.convertJson2Obj(jsonContent, subClassz));
//			}
//			SysCacheUtils.refres(sysSettingDto);
//			return sysSettingDto;
//		} catch (Exception e) {
//			logger.error("刷新缓存失败", e);
//			throw new BusinessException("刷新缓存失败");
//		}
//	}

	@Override
	public SysSettingDto refresCache() {
		try {
			SysSettingDto sysSettingDto = new SysSettingDto();
			List<SysSetting> list = sysSettingMapper.selectList(new SysSettingQuery());
			for (SysSetting sysSetting : list) {
				String jsonContent = sysSetting.getJsonContent();
				if (StringTools.isEmpty(jsonContent)) {
					continue;
				}
				String code = sysSetting.getCode();
				SysSettingCodeEnum sysSettingCodeEnum = SysSettingCodeEnum.getByCode(code);
				String propName = sysSettingCodeEnum.getPropName();
				Class<?> subClassz = Class.forName(sysSettingCodeEnum.getClassz());
				Object subObject = JsonUtils.convertJson2Obj(jsonContent, subClassz);
				switch (propName) {
					case "auditSetting":
						sysSettingDto.setAuditSetting((SysSetting4AuditDto) subObject);
						break;
					case "commentSetting":
						sysSettingDto.setCommentSetting((SysSetting4CommentDto) subObject);
						break;
					case "emailSetting":
						sysSettingDto.setEmailSetting((SysSetting4EmailDto) subObject);
						break;
					case "likeSetting":
						sysSettingDto.setLikeSetting((SysSetting4LikeDto) subObject);
						break;
					case "postSetting":
						sysSettingDto.setPostSetting((SysSetting4PostDto) subObject);
						break;
					case "registerSetting":
						sysSettingDto.setRegisterSetting((SysSetting4RegisterDto) subObject);
						break;
					default:
						logger.warn("未知的属性名称: {}", propName);
						break;
				}
			}
			SysCacheUtils.refres(sysSettingDto);
			return sysSettingDto;
		} catch (Exception e) {
			logger.error("刷新缓存失败", e);
			throw new BusinessException("刷新缓存失败");
		}
	}

	@Override
	public void saveSetting(SysSettingDto settingDto) {
		try {
			for (SysSettingCodeEnum codeEnum : SysSettingCodeEnum.values()) {
				String propName = codeEnum.getPropName();
				Object obj = getPropertyValue(settingDto, propName);
				if (obj != null) {
					SysSetting setting = new SysSetting();
					setting.setCode(codeEnum.getCode());
					setting.setJsonContent(JsonUtils.convertObj2Json(obj));
					sysSettingMapper.insertOrUpdate(setting);
				}
			}
		} catch (Exception e) {
			logger.error("保存设置失败", e);
			throw new BusinessException("保存设置失败");
		}
	}

	private Object getPropertyValue(SysSettingDto settingDto, String propertyName) {
		switch (propertyName) {
			case "auditSetting":
				return settingDto.getAuditSetting();
			case "commentSetting":
				return settingDto.getCommentSetting();
			case "emailSetting":
				return settingDto.getEmailSetting();
			case "likeSetting":
				return settingDto.getLikeSetting();
			case "postSetting":
				return settingDto.getPostSetting();
			case "registerSetting":
				return settingDto.getRegisterSetting();
			default:
				return null;
		}
	}
}
